/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package controller;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import javax.swing.SwingUtilities;
import model.Composite;
import model.IComposite;
import view.FrameOfDigitalNetWork;

/**
 *
 * @author Máté
 */
public class Main {     //main class

    private static Integer index;
    private static HashMap<Integer, Object> elements;
    private static Iterator<String> iterator = null;
    private static List<String> commands = null;

    static {
        index = 0;
        elements = new HashMap<Integer, Object>();
        commands = new ArrayList<String>();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                new FrameOfDigitalNetWork().setVisible(true);
            }
        });
    }

    public static Integer putElement(Object element, Integer parentId) {
        if (parentId != null) {
            if ((elements.get(parentId) instanceof Composite) && (element instanceof IComposite)) {
                ((Composite) elements.get(parentId)).addElement((IComposite) element);
            }
        }

        elements.put(index, element);
        index++;

        return index - 1;
    }

    public static HashMap<Integer, Object> getElements() {
        return elements;
    }

    public static Integer getKey(Object value) {
        Integer key = null;

        for (Entry<Integer, Object> current : elements.entrySet()) {
            if (current.getValue().equals(value)) {
                key = current.getKey();
            }
        }

        return key;
    }

    public static Integer getCompositeIdByContainingElement(IComposite composite) {
        Integer id = null;

        for (Integer i = 0; i < index; i++) {
            if (elements.containsKey(i) && elements.get(i) instanceof Composite) {
                if (((Composite) elements.get(i)).contains(composite)) {
                    id = i;
                }
            }
        }

        return id;
    }

    public static Integer getIndex() {
        return index;
    }

    public static void reset() {
        index = 0;
        elements = new HashMap<Integer, Object>();
        iterator = null;
        commands = new ArrayList<String>();
    }

    public static String noteElements()
    {
        HashMap hm = getElements();
        StringBuilder board = new StringBuilder();

        for (Integer i = 0; i<getIndex(); i++)
        {
            if (hm.containsKey(i))
            {
                Integer j = new Integer(i.intValue());

                board.append(i.toString());
                board.append("\t");

                if (hm.get(i) instanceof IComposite)
                {
                    while (getCompositeIdByContainingElement((IComposite) hm.get(j)) != null)
                    {
                          board.append("\t");
                          j = getCompositeIdByContainingElement((IComposite) hm.get(j));
                    }
                }
                board.append(hm.get(i).getClass().getSimpleName().toString());
                board.append("\n");
            }
        }

        return board.toString();
    }

    public static void readFile(String path) throws IOException {
        try {
            BufferedReader reader = new BufferedReader(new FileReader(path));
            String line;
            Reader.getInstance().resetDescription();
            while ((line = reader.readLine()) != null) {
                commands.add(line);
                Reader.getInstance().buildDescription(line);
            }
            iterator = commands.iterator();
        }catch (FileNotFoundException ex) {
            System.out.println("Error: File not found!");
        }catch (IOException ex) {
            System.out.println("Error: I/O error!");
        }
    }

    public static String readCommands(){
        String command = "stop";
        if (iterator.hasNext())
            command = iterator.next();
        return command;
    }

    public static void gridToFile(String path) {
        try {
            Reader.getInstance().writeDescription(path);
        } catch (IOException ex) {
            System.out.println("Error: I/O error!");
        }
    }

//    public static void main(String[] args) {    //segedvaltozok inicializacioja
//        Boolean isRunning = true;
//        Boolean readingFromFile = false;
//        Integer index = new Integer(0);
//        Integer option = new Integer(0);
//        HashMap<Integer, Object> elements = new HashMap<Integer, Object>();
//        Composite compositeToModify = null;
//        Integer idOfCompositeToModify = null;
//        Scanner in = new Scanner(System.in);
//        String command = null;
//        Iterator<String> iterator = null;
//        List<String> commands = null;
//
//        PictureContainer pc = new PictureContainer();
//        pc.getPictures();
//
//        while (isRunning) {     // fő ciklus
//
//            if (readingFromFile) {
//                if (iterator.hasNext()) {
//                    command = iterator.next();      //filebol beolvassuk a halozat
//                    option = selectedCase(command); //felepitesere vonatkozo parancsokat
//                } else {
//                    readingFromFile = false;
//                }
//            }
//
//            if (!readingFromFile) {
//                command = in.nextLine();
//                option = selectedCase(command);
//            }
//
//            switch (option) {   //a program fo elagazasa
//                case 0:
//                    //eset: test
//                    System.out.println("Circuit testing started!");
//
//                    for (Integer i = 0; i < index; i++) {
//                        if (elements.containsKey(i)) {
//                            Object current = elements.get(i);   //current: az aktualis elem
//
//                            if (current instanceof Display) {
//                                Display display = (Display) current;
//
//                                if (display.isConnected()) {    //kiiratjuk a display allapotat
//                                    System.out.println("Display id: " + i.toString() + " , value: " + display.isOn());
//                                } else {
//                                    System.out.println("Error: Connection error!"); //ha nincs felcsatlakoztatva a
//                                                                                    //display, hibat dobunk
//                                }
//                            } else if (current instanceof Oscilloscope) {       //oszcilloszkop
//                                Oscilloscope oscilloscope = (Oscilloscope) current;
//
//                                if (oscilloscope.isConnected()) {
//                                    StringBuilder builder = new StringBuilder();
//
//                                    builder.append("Oscilloscope id: ");
//                                    builder.append(i.toString());
//                                    builder.append(", values:");
//                                                        //kiiratjuk az oszcilloszkop ertekeit
//                                    for (Boolean value : oscilloscope.getStateList()) {
//                                        builder.append(" ");
//                                        builder.append(value.toString());
//                                    }
//
//                                    System.out.println(builder.toString());
//                                } else {
//                                    System.out.println("Error: Connection error!"); //ha nincs csatlakoztatva, hibat dobunk
//                                }
//                            }
//                        }
//                    }
//
//                    break;
//                case 1:     //eset: kilepes
//                    // exit
//                    isRunning = false;
//                    System.out.println("Program stopped!");
//                    break;
//                case 2:
//                    //eset: addSwitch
//                    if (command.indexOf(")") == 10) {
//                        elements.put(index, new Switch());
//                        Reader.getInstance().buildDescription(command);
//                        System.out.println("Switch added with ID: " + index.toString());
//                        index++;    //uj switchet adunk hozza megfelelo indexszel
//                    } else {
//                        System.out.println("Error: Wrong input number!");
//                    }
//                    break;
//                case 3:
//                    //eset: addGenerator
//                    int bracketpos = command.indexOf(")");
//                    boolean valid = true;
//                    int i = 13;                 //generatort adunk hozza
//                    List<Boolean> arglist = new ArrayList<Boolean>();
//                    while (valid && i < bracketpos) {
//                        Integer inputNumber = new Integer(String.valueOf(command.charAt(i)));
//                        if ((inputNumber != 0 && inputNumber != 1) || (command.charAt(i + 1) != ',' && command.charAt(i + 1) != ')')) {
//                            valid = false;
//                                                //ellenorizzuk, hogy a bemeneti bitsorozat formatuma megfelelo-e
//                        } else {
//                            if (inputNumber == 0) {
//                                arglist.add(false);
//                            } else {
//                                arglist.add(true);
//                            }
//                        }
//                        i += 2;
//                    }
//                    if (valid) {                                //generator elkeszult
//                        Generator gen = new Generator();
//                        gen.setPattern(arglist);
//                        elements.put(index, gen);
//                        Reader.getInstance().buildDescription(command);
//                        System.out.println("Generator added with ID: " + index.toString());
//                        index++;
//                    } else {
//                        System.out.println("Error: Wrong input number!");
//                    }
//                    break;
//                case 4:
//                                                             //eset: addDisplay
//                    if (command.indexOf(")") == 11) {
//                        elements.put(index, new Display());
//                        Reader.getInstance().buildDescription(command);
//                        System.out.println("Display added with ID: " + index.toString());
//                        index++;
//                                                               //displayt adunk hozza
//                    } else {
//                        System.out.println("Error: Wrong input number!");
//                    }
//                    break;
//                case 5:
//                    // addOrGate
//                    try {
//                        Integer inputNumber = new Integer(String.valueOf(command.charAt(10)));
//
//                        if (inputNumber == 2 || inputNumber == 3 || inputNumber == 4) {
//
//                            //bemenetek szamanak ellenorzese
//
//                            OrGate orGate = new OrGate();
//                            elements.put(index, orGate);        //vagy kaput adunk hozza
//
//                            if (compositeToModify != null) {
//                                compositeToModify.addElement(orGate);
//                            }
//
//                            Reader.getInstance().buildDescription(command);
//                            System.out.println("Or gate added with ID: " + index.toString());
//                            index++;
//                                                                //vagy kapu elkeszult
//                        } else {
//                            System.out.println("Error: Wrong input number!");
//                        }
//                    } catch (Exception exception) {     //hibas bemenet vagy nem megfelelo szamu
//                                                        //lab eseten hibat dobunk
//                        System.out.println("Error: Wrong parameters!");
//                    }
//                    break;
//                case 6:
//                    //eset: addAndGate
//                    try {
//                        Integer inputNumber = new Integer(String.valueOf(command.charAt(11)));
//
//                        if (inputNumber == 2 || inputNumber == 3 || inputNumber == 4) {
//
//                            //es kapu bemenetei szamanak ellenorzese
//
//                            AndGate andGate = new AndGate();
//                            elements.put(index, andGate);       //es kaput adunk hozza
//                            Reader.getInstance().buildDescription(command);
//
//                            if (compositeToModify != null) {
//                                compositeToModify.addElement(andGate);
//                            }
//
//                            System.out.println("And gate added with ID: " + index.toString());
//                            index++;
//                                                                //es kapu elkeszult
//                        } else {
//                            System.out.println("Error: Wrong input number!");
//                        }
//
//                                //hibas bemenet vagy nem megfelelo szamu lab
//                                //eseten hibat dobunk
//
//                    } catch (Exception exception) {
//                        System.out.println("Error: Wrong parameters!");
//                    }
//                    break;
//                case 7:
//                    //eset: addInverter
//                    if (command.indexOf(")") == 12) {
//                        Inverter inverter = new Inverter();
//                        elements.put(index, inverter);
//                        Reader.getInstance().buildDescription(command);
//
//                                                    //invertert adunk hozza
//
//                        if (compositeToModify != null) {
//                            compositeToModify.addElement(inverter);
//                        }
//
//                        System.out.println("Inverter added with ID: " + index.toString());
//                        index++;
//                                                            //inverter elkeszült
//                    } else {
//                        System.out.println("Error: Wrong input number!");
//
//                                //csak egy bemenete lehet
//                    }
//                    break;
//                case 8:
//                    //eset: addOscilloscope
//                    if (command.indexOf(")") == 16) {
//                        elements.put(index, new Oscilloscope());
//                        Reader.getInstance().buildDescription(command);
//                        System.out.println("Oscilloscope added with ID: " + index.toString());
//                        index++;
//
//                                                //oszcilloszkopot adunk hozza
//                    } else {
//                        System.out.println("Error: Wrong input number!");
//
//                                    //csak egy bemenete lehet
//                    }
//                    break;
//                case 9:
//                    //eset: addComposite
//                    try {
//                        Integer inputNumber = new Integer(String.valueOf(command.charAt(13)));
//                        Integer outputNumber = new Integer(String.valueOf(command.charAt(15)));
//
//                        if (inputNumber < 1 || inputNumber > 4 || outputNumber < 1 || outputNumber > 4) {
//                            System.out.println("Error: Wrong input or output number!");
//                        } else {
//                            compositeToModify= new Composite();
//                            idOfCompositeToModify=index;
//                            //composite elemet adunk hozza
//                            Composite composite = new Composite();
//                            elements.put(index, composite);
//                            Reader.getInstance().buildDescription(command);
//
//                            if (compositeToModify != null) {
//                                compositeToModify.addElement(composite);
//                            }
//
//                            System.out.println("Composite added with ID: " + index.toString());
//                            index++;
//                            //composite elem elkeszult
//
//                            for (int j = 0; j < inputNumber; j++) {
//                                Port port = new Port(false);
//                                elements.put(index, port);
//                                composite.addElement(port);     // input portokat adunk hozza
//                                System.out.println("Port added with ID: " + index.toString());
//                                index++;
//                            }
//
//                            for (int j = 0; j < outputNumber; j++) {
//                                Port port = new Port(true);
//                                elements.put(index, port);
//                                composite.addElement(port);         //output portokat adunk hozza
//                                System.out.println("Port added with ID: " + index.toString());
//                                index++;
//                            }
//                        }
//                    } catch (Exception e) {
//                        System.out.println("Error: Wrong parameters!");
//
//                            //hibas parameterek eseten exception-t dobunk
//                    }
//                    break;
//                case 10:
//                    //eset: wire
//                    try {
//                        Integer inputNumber = new Integer(String.valueOf(command.charAt(5)));
//                        Integer inputNumber2 = new Integer(String.valueOf(command.charAt(7)));
//
//                        if (!(elements.get(inputNumber) instanceof Display) && !(elements.get(inputNumber) instanceof Oscilloscope) && !(elements.get(inputNumber2) instanceof Source)) {
//                            if (elements.get(inputNumber) instanceof Source) {
//                                Source left = (Source) elements.get(inputNumber);
//
//                                if (elements.get(inputNumber2) instanceof Display) {
//                                    Display right = (Display) elements.get(inputNumber2);
//
//                                    left.addOutput(right);
//                                    right.setConnected(true);
//
//                                    System.out.println("Items connected.");
//                                    Reader.getInstance().buildDescription(command);
//                                } else if (elements.get(inputNumber2) instanceof Gate) {
//                                    Gate right = (Gate) elements.get(inputNumber2);
//
//                                    left.addOutput(right);
//
//                                    System.out.println("Items connected.");
//                                    Reader.getInstance().buildDescription(command);
//                                } else if (elements.get(inputNumber2) instanceof Oscilloscope) {
//                                    Oscilloscope right = (Oscilloscope) elements.get(inputNumber2);
//
//                                    left.addOutput(right);
//                                    right.setConnected(true);
//
//                                    System.out.println("Items connected.");
//                                    Reader.getInstance().buildDescription(command);
//                                } else if (elements.get(inputNumber2) instanceof Port) {
//                                    Port right = (Port) elements.get(inputNumber2);
//
//                                    left.addOutput(right);
//
//                                    System.out.println("Items connected.");
//                                    Reader.getInstance().buildDescription(command);
//                                } else {
//                                    System.out.println("Error: Wrong ID(s)!");
//                                }
//                            } else if (elements.get(inputNumber) instanceof Gate) {
//                                Gate left = (Gate) elements.get(inputNumber);
//                                if (elements.get(inputNumber2) instanceof Display) {
//                                    Display right = (Display) elements.get(inputNumber2);
//
//                                    left.addOutput(right);
//                                    right.setConnected(true);
//
//                                    System.out.println("Items connected.");
//                                    Reader.getInstance().buildDescription(command);
//                                } else if (elements.get(inputNumber2) instanceof Gate) {
//                                    Gate right = (Gate) elements.get(inputNumber2);
//
//                                    left.addOutput(right);
//
//                                    System.out.println("Items connected.");
//                                    Reader.getInstance().buildDescription(command);
//                                } else if (elements.get(inputNumber2) instanceof Oscilloscope) {
//                                    Oscilloscope right = (Oscilloscope) elements.get(inputNumber2);
//
//                                    left.addOutput(right);
//                                    right.setConnected(true);
//
//                                    System.out.println("Items connected.");
//                                    Reader.getInstance().buildDescription(command);
//                                } else {
//                                    System.out.println("Error: Wrong ID(s)!");
//                                }
//                            } else {
//                                System.out.println("Error: Wrong ID(s)!");
//                            }
//                        } else {
//                            System.out.println("Error: Wrong ID(s)!");
//                        }
//                    } catch (Exception exception) {
//                        System.out.println("Error: Wrong parameters!");
//                    }
//                    break;
//                case 11:
//                    // switch
//                    try {
//                        Integer switchId = new Integer(String.valueOf(command.charAt(7)));
//
//                        if (elements.get(switchId) instanceof Switch) {
//                            Switch sw = (Switch) elements.get(switchId);
//                            sw.turn();
//
//                            for (Integer i2 = 0; i2 < index; i2++) {
//                                if (elements.containsKey(i2)) {
//                                    Object current = elements.get(i2);
//
//                                    if (current instanceof Display) {
//                                        Display display = (Display) current;
//
//                                        if (display.isConnected()) {
//                                            System.out.println("Display id: " + i2.toString() + " , value: " + display.isOn());
//                                        } else {
//                                            System.out.println("Error: Connection error!");
//                                        }
//                                    } else if (current instanceof Oscilloscope) {
//                                        Oscilloscope oscilloscope = (Oscilloscope) current;
//
//                                        if (oscilloscope.isConnected()) {
//                                            StringBuilder builder = new StringBuilder();
//
//                                            builder.append("Oscilloscope id: ");
//                                            builder.append(i2.toString());
//                                            builder.append(", values:");
//
//                                            for (Boolean value : oscilloscope.getStateList()) {
//                                                builder.append(" ");
//                                                builder.append(value.toString());
//                                            }
//
//                                            System.out.println(builder.toString());
//                                        } else {
//                                            System.out.println("Error: Connection error!");
//                                        }
//                                    }
//                                }
//                            }
//                        } else {
//                            System.out.println("Error: Wrong ID!");
//                        }
//                    } catch (Exception exception) {
//                        System.out.println("Error: Wrong parameters!");
//                    }
//                    break;
//                case 12:
//                    // step
//                    try {
//                        Integer generatorId = new Integer(String.valueOf(command.charAt(5)));
//
//                        if (elements.get(generatorId) instanceof Generator) {
//                            Generator generator = (Generator) elements.get(generatorId);
//                            generator.step();
//
//                            for (Integer i3 = 0; i3 < index; i3++) {
//                                if (elements.containsKey(i3)) {
//                                    Object current = elements.get(i3);
//
//                                    if (current instanceof Display) {
//                                        Display display = (Display) current;
//
//                                        if (display.isConnected()) {
//                                            System.out.println("Display id: " + i3.toString() + " , value: " + display.isOn());
//                                        } else {
//                                            System.out.println("Error: Connection error!");
//                                        }
//                                    } else if (current instanceof Oscilloscope) {
//                                        Oscilloscope oscilloscope = (Oscilloscope) current;
//
//                                        if (oscilloscope.isConnected()) {
//                                            StringBuilder builder = new StringBuilder();
//
//                                            builder.append("Oscilloscope id: ");
//                                            builder.append(i3.toString());
//                                            builder.append(", values:");
//
//                                            for (Boolean value : oscilloscope.getStateList()) {
//                                                builder.append(" ");
//                                                builder.append(value.toString());
//                                            }
//
//                                            System.out.println(builder.toString());
//                                        } else {
//                                            System.out.println("Error: Connection error!");
//                                        }
//                                    }
//                                }
//                            }
//                        } else {
//                            System.out.println("Error: Wrong ID!");
//                        }
//                    } catch (Exception exception) {
//                        System.out.println("Error: Wrong parameters!");
//                    }
//                    break;
//                case 13:
//                    // end
//                    if (compositeToModify != null) {
//                        System.out.println("Edited composite with id: " + idOfCompositeToModify.toString());
//                        compositeToModify = null;
//                        idOfCompositeToModify = null;
//                        Reader.getInstance().buildDescription(command);
//                    } else {
//                        System.out.println("Error: Wrong command!");
//                    }
//                    break;
//                case 14:
//                    //delete
//                    break;
//                case 15:
//                    //modComposite
//                    try {
//                        Integer id = new Integer(String.valueOf(command.charAt(14)));
//                        if (elements.get(id) instanceof Composite) {
//                            compositeToModify = (Composite) elements.get(id);
//                            idOfCompositeToModify = id;
//                            Reader.getInstance().buildDescription(command);
//                        } else {
//                            System.out.println("Error: Wrong ID!");
//                        }
//                    } catch (Exception e) {
//                        System.out.println("Error: Wrong command!");
//                    }
//                    break;
//                case 16:
//                    //readFile
//                    try {
//                        String path = command.replace("readFile(", "");
//                        path = path.replace(")", "");
//                        BufferedReader reader = new BufferedReader(new FileReader(path));
//                        commands = new ArrayList<String>();
//                        String line;
//                        Reader.getInstance().resetDescription();
//                        while ((line = reader.readLine()) != null) {
//                            commands.add(line);
//                            Reader.getInstance().buildDescription(line);
//                        }
//                    } catch (FileNotFoundException ex) {
//                        System.out.println("Error: File not found!");
//                    } catch (IOException ex) {
//                        System.out.println("Error: I/O error!");
//                    }
//
//                    index = 0;
//                    elements = new HashMap<Integer, Object>();
//                    ResetHandler.newWires();
//                    ScopeWatch.newOscilloscope();
//                    readingFromFile = true;
//                    iterator = commands.iterator();
//                    break;
//                case 17:
//                    //writeGridToFile
//                    try {
//                        String path = command.replace("writeGridToFile(", "");
//                        path = path.replace(")", "");
//                        Reader.getInstance().writeDescription(path);
//                    } catch (IOException ex) {
//                        System.out.println("Error: I/O error!");
//                    }
//                    break;
//                case 18:
//                    //writeOutputToFile
//                    try {
//                        String path = command.replace("writeOutputToFile(", "");
//                        path = path.replace(")", "");
//                        Reader.getInstance().resetOutuput();
//                        for (Integer j = 0; j < index; j++) {
//                            if (elements.containsKey(j)) {
//                                if(elements.get(j) instanceof Display){
//                                    Display display = (Display)elements.get(j);
//                                    Reader.getInstance().buildOutput("Display id: " + j.toString() + " , value: " + display.isOn());
//                                }else if(elements.get(j) instanceof Oscilloscope){
//                                    Oscilloscope oscilloscope = (Oscilloscope)elements.get(j);
//                                    StringBuilder builder = new StringBuilder();
//                                    builder.append("Oscilloscope id: ");
//                                    builder.append(j.toString());
//                                    builder.append(", values:");
//                                    for (Boolean value : oscilloscope.getStateList()) {
//                                        builder.append(" ");
//                                        builder.append(value.toString());
//                                    }
//                                    Reader.getInstance().buildOutput(builder.toString());
//                                }
//                            }
//                        }
//                        Reader.getInstance().writeOutput(path);
//                    } catch (IOException ex) {
//                        System.out.println("Error: I/O error!");
//                    }
//                    break;
//
//                default:
//                    System.out.println("Error: No such command!");
//                    break;
//            }
//        }
//    }
//
//    //felhasználó input feldolgozása
//    private static Integer selectedCase(String command) {
//        if (command.equals("test")) {
//            return 0;
//        } else if (command.equals("exit")) {
//            return 1;
//        } else if (command.matches("addSwitch\\(\\d*\\)")) {
//            return 2;
//        } else if (command.matches("addGenerator\\(\\d+(\\,\\d+)*\\)")) {
//            return 3;
//        } else if (command.matches("addDisplay\\(\\d*\\)")) {
//            return 4;
//        } else if (command.matches("addOrGate\\(\\d*\\)")) {
//            return 5;
//        } else if (command.matches("addAndGate\\(\\d*\\)")) {
//            return 6;
//        } else if (command.matches("addInverter\\(\\d*\\)")) {
//            return 7;
//        } else if (command.matches("addOscilloscope\\(\\d*\\)")) {
//            return 8;
//        } else if (command.matches("addComposite\\(\\d+\\,\\d+\\)")) {
//            return 9;
//        } else if (command.matches("wire\\(\\d+\\,\\d+\\)")) {
//            return 10;
//        } else if (command.matches("switch\\(\\d+\\)")) {
//            return 11;
//        } else if (command.matches("step\\(\\d+\\)")) {
//            return 12;
//        } else if (command.equals("end")) {
//            return 13;
//        } else if (command.matches("delete\\(\\d+\\)")) {
//            return 14;
//        } else if (command.matches("modComposite\\(\\d+\\)")) {
//            return 15;
//        } else if (command.matches("readFile\\(.*\\)")) {
//            return 16;
//        } else if (command.matches("writeGridToFile\\(.*\\)")) {
//            return 17;
//        } else if (command.matches("writeOutputToFile\\(.*\\)")) {
//            return 18;
//        } else {
//            return -1;
//        }
//    }
}
